Skip to content

fix: remove xmodulemixin and accept other legacy mxins#230

Open
irtazaakram wants to merge 2 commits intomainfrom
remove-legacy-mixins
Open

fix: remove xmodulemixin and accept other legacy mxins#230
irtazaakram wants to merge 2 commits intomainfrom
remove-legacy-mixins

Conversation

@irtazaakram
Copy link
Copy Markdown
Member

@irtazaakram irtazaakram commented Apr 2, 2026

This PR:

  • renames xblocks_contrib/commonxblocks_contrib/legacy_utils to clearly mark legacy code
  • adds a strong LEGACY — DO NOT USE warning in legacy_utils/xml_utils.py
  • removes XModuleMixin usage and related duplicated logic from xblocks-contrib
  • merges XModuleToXBlockMixin into individual XBlocks
  • removes XmlMixin and moves parse_xml into the Problem block
  • removes RawMixin, keeping only required functionality in the Problem block
  • updates/removes affected tests accordingly
  • reduces dependency on legacy XModule internals and cleans up technical debt

@farhan
Copy link
Copy Markdown
Contributor

farhan commented Apr 10, 2026

Code is crashing on the following test sceneario, it's working fine on the master/main branch.
Test Scenario: Add Video Component (Block) in the Content Library

2026-04-10 11:40:57,493 INFO 27 [edx_rest_framework_extensions.auth.jwt.middleware] [user 4] [ip 172.18.0.1] middleware.py:79 - ('The view BlockFieldsView allows Jwt Authentication. The required permission class, NotJwtRestrictedApplication,', ' was automatically added.')
2026-04-10 11:40:57,509 WARNING 27 [py.warnings] [user 4] [ip 172.18.0.1] warnings.py:112 - /openedx/edx-platform/openedx/core/djangoapps/xblock/runtime/runtime.py:148: UserIdDeprecationWarning: Runtime.user_id is deprecated
  self.user_id = self.user.id

2026-04-10 11:40:57,521 ERROR 27 [root] [user None] [ip None] signals.py:22 - Uncaught exception from None
Traceback (most recent call last):
  File "/openedx/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.12.12/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 515, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 475, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 486, in raise_uncaught_exception
    raise exc
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 512, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.12.12/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/openedx/edx-platform/openedx/core/djangoapps/xblock/rest_api/views.py", line 345, in post
    block.editor_saved(user, old_metadata, old_content)
  File "/mnt/xblocks-contrib/xblocks_contrib/video/video.py", line 584, in editor_saved
    video_config_service.handle_editor_saved(self, user.id, old_metadata)
  File "/openedx/edx-platform/openedx/core/djangoapps/video_config/services.py", line 314, in handle_editor_saved
    metadata_was_changed_by_user = old_metadata != own_metadata(video_block)
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/edx-platform/xmodule/modulestore/inheritance.py", line 340, in own_metadata
    return block.get_explicitly_set_fields_by_scope(Scope.settings)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'VideoBlockWithMixins' object has no attribute 'get_explicitly_set_fields_by_scope'
Internal Server Error: /api/xblock/v2/xblocks/lb:axim:1:video:848a25e5-b803-4e84-b4bc-23daf842e3f8/fields/
Traceback (most recent call last):
  File "/openedx/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.12.12/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 515, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 475, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 486, in raise_uncaught_exception
    raise exc
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 512, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.12.12/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/openedx/edx-platform/openedx/core/djangoapps/xblock/rest_api/views.py", line 345, in post
    block.editor_saved(user, old_metadata, old_content)
  File "/mnt/xblocks-contrib/xblocks_contrib/video/video.py", line 584, in editor_saved
    video_config_service.handle_editor_saved(self, user.id, old_metadata)
  File "/openedx/edx-platform/openedx/core/djangoapps/video_config/services.py", line 314, in handle_editor_saved
    metadata_was_changed_by_user = old_metadata != own_metadata(video_block)
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/edx-platform/xmodule/modulestore/inheritance.py", line 340, in own_metadata
    return block.get_explicitly_set_fields_by_scope(Scope.settings)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'VideoBlockWithMixins' object has no attribute 'get_explicitly_set_fields_by_scope'
2026-04-10 11:40:57,624 ERROR 27 [django.request] [user None] [ip None] log.py:253 - Internal Server Error: /api/xblock/v2/xblocks/lb:axim:1:video:848a25e5-b803-4e84-b4bc-23daf842e3f8/fields/
Traceback (most recent call last):
  File "/openedx/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.12.12/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 515, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 475, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 486, in raise_uncaught_exception
    raise exc
  File "/openedx/venv/lib/python3.12/site-packages/rest_framework/views.py", line 512, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.12.12/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/openedx/edx-platform/openedx/core/djangoapps/xblock/rest_api/views.py", line 345, in post
    block.editor_saved(user, old_metadata, old_content)
  File "/mnt/xblocks-contrib/xblocks_contrib/video/video.py", line 584, in editor_saved
    video_config_service.handle_editor_saved(self, user.id, old_metadata)
  File "/openedx/edx-platform/openedx/core/djangoapps/video_config/services.py", line 314, in handle_editor_saved
    metadata_was_changed_by_user = old_metadata != own_metadata(video_block)
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/edx-platform/xmodule/modulestore/inheritance.py", line 340, in own_metadata
    return block.get_explicitly_set_fields_by_scope(Scope.settings)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'VideoBlockWithMixins' object has no attribute 'get_explicitly_set_fields_by_scope'
[10/Apr/2026 11:40:57] "POST /api/xblock/v2/xblocks/lb:axim:1:video:848a25e5-b803-4e84-b4bc-23daf842e3f8/fields/ HTTP/1.1" 500 301212

@farhan
Copy link
Copy Markdown
Contributor

farhan commented Apr 10, 2026

I think we should rewrite following line in the PR description:

removes XModuleMixin usage and related duplicated logic from xblocks-contrib

Removed XModuleMixin as a separate class within xblocks-contrib repo and moved its required methods into the main Blocks class.

@farhan
Copy link
Copy Markdown
Contributor

farhan commented Apr 10, 2026

We should perform following testing steps for all the factored out XBlocks
https://docs.google.com/document/d/1dAy2JLRlxdAu1ZP-KUza4j6Numc0LtIb9ucPQZ1_Bug/edit?tab=t.yk2na281fpnv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rename common folder to legacy_utils for the clarity Remove legacy XModule mixins from xblocks-contrib XBlocks

2 participants